#include "IISAudio/IISAudio.h"

#include <stdint.h>

int32_t *samples_32bit;//读出来的原始32位数据，长度128
int16_t *samples_16bit;//转换后的16位数据，长度128
uint8_t *samples_8bit ;//转换后的8位数据，长度128
int16_t *recive_16bit_list;//接收后转换的16位数据，长度128

//mic读取音频配置
const i2s_config_t rec_i2s_config = {
      .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
      .sample_rate = SAMPLE_RATE,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
      .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
      .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S | I2S_COMM_FORMAT_I2S),
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 2,
      .dma_buf_len = 256,//单位是bits_per_sample
      };
//i2s扬声器播放配置
const i2s_config_t spk_i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = SAMPLE_RATE,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
      .communication_format =(i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_MSB),
      .intr_alloc_flags = 0,
      .dma_buf_count = 2,
      .dma_buf_len = 256,
};
const i2s_pin_config_t rec_pin_config = {
      .bck_io_num = 14,   // BCKL
      .ws_io_num = 15,    // LRCL
      .data_out_num = -1, // not used (only for speakers)
      .data_in_num = 32   // DOUT3
};
const i2s_pin_config_t spk_pin_config = {
      .bck_io_num = 26,
      .ws_io_num = 22,
      .data_out_num = 25,
      .data_in_num = -1   //Not used
};  
void I2SInit()
{
  samples_32bit = (int32_t *)malloc(sizeof(int32_t) * 128);
  samples_16bit = (int16_t *)malloc(sizeof(int16_t) * 128);
  samples_8bit =  (uint8_t *)malloc(sizeof(uint8_t) * 128);
  recive_16bit_list =  (int16_t *)malloc(sizeof(int16_t) * 128);
  esp_err_t err;
  err = i2s_driver_install(REC_I2S_PORT, &rec_i2s_config, 0, NULL);
  CHECK(err);
  err = i2s_set_pin(REC_I2S_PORT, &rec_pin_config);
  CHECK(err);
  err = i2s_driver_install(SPK_I2S_PORT, &spk_i2s_config, 0, NULL);
  CHECK(err);
  err = i2s_set_pin(SPK_I2S_PORT, &spk_pin_config);
  CHECK(err);
  } 

  void I2SDeinit()
{
    // 释放分配的内存
  free(samples_32bit);
  free(samples_16bit);
  free(samples_8bit);
  free(recive_16bit_list);
  esp_err_t err;
  err = i2s_driver_uninstall(REC_I2S_PORT);
  CHECK(err);
  err = i2s_driver_uninstall(SPK_I2S_PORT);
  CHECK(err);
}


void highPassFilter(int16_t *samples, int count) {
    static float prev_sample = 0;
    const float alpha = 1.50f; // 调整此值以改变滤波器强度
    for (int i = 0; i < count; i++) {
        float current = (float)samples[i];
        float filtered = alpha * (prev_sample + current - prev_sample);
        prev_sample = current;
        samples[i] = (filtered > INT16_MAX) ? INT16_MAX : 
                     (filtered < -INT16_MAX) ? -INT16_MAX : 
                     (int16_t)filtered;
    }
}
#define WINDOW_SIZE 1024
void dynamicNoiseGate(int16_t *samples, int count) {
    static int16_t audio_history[WINDOW_SIZE] = {0};
    static int history_index = 0;
    static float noise_threshold = 1000.0f;  // 初始阈值

    for (int i = 0; i < count; i++) {
        // 更新音频历史
        audio_history[history_index] = abs(samples[i]);
        history_index = (history_index + 1) % WINDOW_SIZE;

        // 每处理WINDOW_SIZE个样本就更新一次噪声阈值
        if (i % WINDOW_SIZE == 0) {
            int sum = 0;
            for (int j = 0; j < WINDOW_SIZE; j++) {
                sum += audio_history[j];
            }
            noise_threshold = (float)sum / WINDOW_SIZE * 1.5f;  // 1.5是一个可调整的因子
        }

        // 应用噪声门
        if (abs(samples[i]) < noise_threshold) {
            samples[i] = 0;
        }
    }
}
#define FILTER_TAP_NUM 4

void iirFilter(int16_t *samples, int count) {
    static float filter_taps[FILTER_TAP_NUM] = {0.1f, 0.2f, 0.3f, 0.4f};
    static float filter_state[FILTER_TAP_NUM] = {0};

    for (int i = 0; i < count; i++) {
        float input = (float)samples[i];
        float output = 0;

        // 移动状态数组
        for (int j = FILTER_TAP_NUM - 1; j > 0; j--) {
            filter_state[j] = filter_state[j-1];
        }
        filter_state[0] = input;

        // 应用滤波器
        for (int j = 0; j < FILTER_TAP_NUM; j++) {
            output += filter_taps[j] * filter_state[j];
        }

        samples[i] = (output > INT16_MAX) ? INT16_MAX : 
                     (output < -INT16_MAX) ? -INT16_MAX : 
                     (int16_t)output;
    }
}
void preEmphasis(int16_t *samples, int count) {
    static float prev_sample = 0;
    const float alpha = 0.95f;  // 典型值，可以调整

    for (int i = 0; i < count; i++) {
        float current = (float)samples[i];
        float preemphasized = current - alpha * prev_sample;
        prev_sample = current;

        samples[i] = (preemphasized > INT16_MAX) ? INT16_MAX : 
                     (preemphasized < -INT16_MAX) ? -INT16_MAX : 
                     (int16_t)preemphasized;
    }
}
int I2Sread(int16_t *samples, int count) {
    static int32_t samples_32bit[128];  // 假设最大读取128个样本
    size_t bytes_read = 0;

    if (count > 128) {
        count = 128;  // 限制最大读取数量
    }

    i2s_read(REC_I2S_PORT, (char *)samples_32bit, sizeof(int32_t) * count, &bytes_read, portMAX_DELAY);
    int samples_read = bytes_read / sizeof(int32_t);

    // 转换并应用初始处理
    for (int i = 0; i < samples_read; i++) {
        int32_t temp = samples_32bit[i] >> 11;
        samples[i] = (temp > INT16_MAX) ? INT16_MAX : (temp < -INT16_MAX) ? -INT16_MAX : (int16_t)temp;
    }
    return samples_read;
}

void covert_bit(int16_t *temp_samples_16bit,uint8_t*temp_samples_8bit,uint8_t len )//16位数据转成8位
{
  for(uint8_t i=0;i<len;i++)
  {
    temp_samples_8bit[i]=(temp_samples_16bit[i] + 32768) >> 8;
  }
    
}
void I2Swrite(int16_t *samples, int count)//数据写入IIS
{
    size_t bytes_written;
    i2s_write(SPK_I2S_PORT, samples, sizeof(uint16_t)*count*2, &bytes_written, portMAX_DELAY); 
}
